package org.fuys.etp.registry.impl;

import lombok.extern.slf4j.Slf4j;
import org.fuys.etp.core.EtpPersistentConfig;
import org.fuys.etp.core.EtpRegistryConfig;
import org.fuys.etp.core.model.res.EtpGlobalUpdateRes;
import org.fuys.etp.registry.IEtpRegistry;
import org.fuys.etp.registry.model.EtpRegistryHandleRes;
import org.redisson.Redisson;
import org.redisson.api.*;
import org.redisson.api.map.event.EntryEvent;
import org.redisson.api.map.event.EntryUpdatedListener;
import org.redisson.client.codec.StringCodec;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

/**
 * @projectName: fuys-etp-final
 * @package: org.fuys.etp.registry.impl
 * @className: RedisEtpRegistry
 * @author: WangJing
 * @description: Redis注册与配置中心
 * @date: 2025/3/1 11:07
 * @version: 1.0
 */
@Component
@Configuration
@Slf4j
public class RedisEtpRegistry implements IEtpRegistry {


    @Resource
    private EtpPersistentConfig etpPersistentConfig;

    @Resource
    private EtpRegistryConfig etpRegistryConfig;

    @Resource
    private RedissonClient redissonClient;

    RMapCache<String,Object> config;

    private static final String INSTANCE_PREFIX = "fuys:etp:instance";

    private static final String GLOBAL_CONFIG_PREFIX = "fuys:etp:global:config";

    @Override
    public EtpRegistryHandleRes registry() {
        try {
            final RBucket<String> instance = redissonClient.getBucket(INSTANCE_PREFIX +
                    etpRegistryConfig.getName());
            instance.set("running");
            final RMap<String, Object> globalConfig = redissonClient.getMap(GLOBAL_CONFIG_PREFIX +
                    etpRegistryConfig.getName());
            globalConfig.putAll(etpPersistentConfig.toMap());
            return EtpRegistryHandleRes.builder().result(true).build();
        } catch (Exception e) {
            e.printStackTrace();
            return EtpRegistryHandleRes.builder().result(false).msg(e.getMessage()).build();
        }
    }

    @Override
    public EtpRegistryHandleRes cancelRegistry() {
        redissonClient.getKeys().delete(INSTANCE_PREFIX +
                etpRegistryConfig.getName(),GLOBAL_CONFIG_PREFIX +
                etpRegistryConfig.getName());
        return EtpRegistryHandleRes.builder().result(true).build();
    }

    @Override
    public EtpRegistryHandleRes configListenerHandle(boolean result, String msg,
                                                     String key, Object value, Object oldValue) {
        return null;
    }


    @PostConstruct
    public void initListener(){
        this.registry();
        config = redissonClient.getMapCache("fuys:etp:global:config");
        config.addListener(new EntryUpdatedListener<String, Object>() {
            @Override
            public void onUpdated(EntryEvent<String, Object> entryEvent) {
                final EtpGlobalUpdateRes updateRes = etpPersistentConfig.updateByUpdater(
                        entryEvent.getKey(), entryEvent.getValue());
                if(updateRes.isResult()){
                    log.info("Fuys etp 全局配置更新成功。{}",entryEvent.getKey());
                }else{
                    log.info("Fuys etp 全局配置更新失败。{}",entryEvent.getKey());
                }
                configListenerHandle(updateRes.isResult(),updateRes.getMsg(),entryEvent.getKey(),entryEvent.getValue(),
                        entryEvent.getOldValue());
            }
        });
    }

    @Bean
    public RedissonClient redissonClient(){
        Config config = new Config();
        config.setCodec(JsonJacksonCodec.INSTANCE);

        config.useSingleServer()
                .setAddress("redis://" + etpRegistryConfig.getAddress() + ":" +
                        etpRegistryConfig.getPort())
                .setPassword(etpRegistryConfig.getPassword())
                .setConnectionPoolSize(etpRegistryConfig.getPoolSize())
                .setConnectionMinimumIdleSize(etpRegistryConfig.getMinIdleSize())
                .setIdleConnectionTimeout(etpRegistryConfig.getIdleTimeout())
                .setConnectTimeout(etpRegistryConfig.getConnectTimeout())
                .setRetryAttempts(etpRegistryConfig.getRetryAttempts())
                .setRetryInterval(etpRegistryConfig.getRetryInterval())
                .setPingConnectionInterval(etpRegistryConfig.getPingInterval())
                .setKeepAlive(etpRegistryConfig.isKeepAlive())
        ;

        RedissonClient redissonClient = Redisson.create(config);

        log.info("Fuys etp 注册器（redis）链接初始化完成。{} {} {}", etpRegistryConfig.getAddress(),
                etpRegistryConfig.getPort(), !redissonClient.isShutdown());

        return redissonClient;
    }

    @PreDestroy
    public void destroy(){
        this.cancelRegistry();
        redissonClient.shutdown();
    }

}
